﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Forms;
using AppUpgrader.Deploy;
using AppUpgrader.Download;
using System.Threading;

namespace AppUpgrader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private NotifyIcon notifyIcon;
        private bool UpdateComplete {get;set;}

        private String newVersion { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            InitNotifyIcon();

            DoUpdate();
        }

        private void InitNotifyIcon()
        {
            this.Visibility = Visibility.Hidden;
            this.notifyIcon = new NotifyIcon();
            this.notifyIcon.BalloonTipText = "自动更新正在运行！";
            this.notifyIcon.Text = "自动更新应用程序！";
            this.notifyIcon.Icon = AppUpgrader.Properties.Resources.Updater_48;
            this.notifyIcon.Visible = true;
            this.notifyIcon.ShowBalloonTip(1000);
            this.notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(notifyIcon_MouseClick);
            System.Windows.Forms.MenuItem item1 = new System.Windows.Forms.MenuItem("显示主界面");
            item1.Click += new EventHandler(item1_Click);
            System.Windows.Forms.MenuItem item2 = new System.Windows.Forms.MenuItem("退出");
            item2.Click += new EventHandler(item2_Click);
            System.Windows.Forms.MenuItem[] menuItems = new System.Windows.Forms.MenuItem[] { item1, item2 };
            this.notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(menuItems);
            this.StateChanged += new EventHandler(MainWindow_StateChanged);
            this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
        }

        void item1_Click(object sender, EventArgs e)
        {
            this.Visibility = Visibility.Visible;
            this.Activate();
        }
        void item2_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        void notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.Visibility == Visibility.Visible)
                {
                    this.Visibility = Visibility.Hidden;
                }
                else
                {
                    this.Visibility = Visibility.Visible;
                    this.Activate();
                }
            }
        }
        void MainWindow_StateChanged(object sender, EventArgs e)
        {
            if (this.WindowState == WindowState.Minimized)
            {
                this.Visibility = Visibility.Hidden;
            }
        }
        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (System.Windows.MessageBox.Show("确定要退出更新应用程序吗？",
                                               "更新应用程序",
                                               MessageBoxButton.YesNo,
                                               MessageBoxImage.Question,
                                               MessageBoxResult.No) == MessageBoxResult.Yes)
            {
                this.notifyIcon.Visible = false;
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        private void DoUpdate()
        {
            ShowText("正在检查更新，请稍等......");
            Upgrader up = new Upgrader();
            VersionManifest version = null;
            try
            {
                version = up.StartCheckVersion();
            }
            catch(Exception ex)
            {
                String msg = "检查新版本时发生错误："+ ex.ToString();
                LogUtils.WriteError(msg);
                System.Windows.MessageBox.Show(msg, "获取更新错误");
                return;
            }

            if (version == null)
            {
                //不需要更新
                ShowText("当前已经是最新版本！");
                this.progressBar1.Visibility = System.Windows.Visibility.Hidden;
                return;
            }

            this.newVersion = version.Version.ToString();
            LogUtils.WriteLog(String.Format("当前最新版本：{0}，更新地址：{1}",version.Version,version.location));

            ShowText(String.Format("正在下载最新版本{0},请稍等......", version.Version));
            String DownloadPath = up.GetDownloadFilePath(version.location);

            DownloadWorker worker = new DownloadWorker(version.location, DownloadPath);
            worker.StateChanged += new StateChangedEvent(worker_StateChanged);
            worker.Complete += new StateChangedEvent(worker_Complete);
            worker.AsynDownloadFile();
        }

        void worker_StateChanged(object sender, StateChangedEventArgs arg)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => {
                this.progressBar1.Value = arg.Percent;
                this.txtTitle.Text = arg.Message;
            }));
        }

        //下载完成，开始安装
        void worker_Complete(object sender, StateChangedEventArgs arg)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                String filePath = arg.Message;
                UpdateApplication(filePath);
            }));
        }

        private void UpdateApplication(String filePath)
        {
            String AppProcessName = "Logistics";
            if (!System.IO.File.Exists(filePath))
            {
                System.Windows.MessageBox.Show("无法找到下载文件:" + filePath, "错误");
                return;
            }
            ShowText("正在安装更新,请稍等......");

            Process[] ps = Process.GetProcessesByName(AppProcessName);
            if (ps != null && ps.Length > 0)
            {
                System.Windows.Forms.MessageBox.Show("应用程序正在运行，更新程序将终止当前应用程序，请保存好相关数据！", "警告");
            }
            //再查一遍，以免用户关闭了进程
            ps = Process.GetProcessesByName(AppProcessName);
            if (ps != null && ps.Length > 0) 
            {
                foreach (Process p in ps)
                    p.Kill();

                //Thread.Sleep(5*1000);
            }
            Thread.Sleep(5000);
            //开始安装
            String ext = System.IO.Path.GetExtension(filePath);
            if (String.Compare(".zip", ext, true) == 0)
            {
                DeployWorker Deploy = new DeployWorker();
                Deploy.StateChanged += new StateChangedEvent(Deploy_StateChanged);
                Deploy.Complete += new StateChangedEvent(Deploy_Complete);
                Deploy.ExceptionOccured += new ExceptionEvent(Deploy_ExceptionOccured);
                Deploy.Asyn_DeployZipFile(filePath);
            }
            else if (String.Compare(".exe", ext, true) == 0)
            {
                System.Diagnostics.Process.Start(filePath);
                Environment.Exit(-1);//退出
            }
            else
            {
                ShowText("更新失败，无法识别的更新文件:" + filePath);
                this.progressBar1.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        void Deploy_ExceptionOccured(object sender, Exception ex)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                ShowText("更新发生异常："+ex.ToString());
                this.progressBar1.Visibility = System.Windows.Visibility.Hidden;
            }));
        }

        void Deploy_StateChanged(object sender, StateChangedEventArgs arg)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                ShowText(arg.Message);
                this.progressBar1.Value = arg.Percent;
            }));
        }
        void Deploy_Complete(object sender, StateChangedEventArgs arg)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                Upgrader.WriteNewVersion(this.newVersion);
                ShowText("更新完成");
                this.progressBar1.Visibility = System.Windows.Visibility.Hidden;
            }));
        }

        private void ShowText(String message)
        {
            this.txtTitle.Text = message;
            this.notifyIcon.BalloonTipText = message;
            LogUtils.WriteLog(message);
        }
    }
}
